package com.yhsoft.bill.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yhsoft.bill.controller.request.SysHkInVo;
import com.yhsoft.bill.controller.request.SysSkInVo;
import com.yhsoft.bill.controller.request.SysYckLogInVo;
import com.yhsoft.bill.controller.request.SysYszkInVo;
import com.yhsoft.bill.controller.response.SalerYfzkOutVo;
import com.yhsoft.bill.controller.response.SysYckLogOutVo;
import com.yhsoft.bill.controller.response.SysYszkOutVo;
import com.yhsoft.bill.entity.SysYszk;
import com.yhsoft.bill.mapper.SysYszkMapper;
import com.yhsoft.bill.service.ISysYszkService;
import com.yhsoft.buyer.entity.BuyerOrder;
import com.yhsoft.buyer.service.IBuyerOrderService;
import com.yhsoft.common.service.TokenService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import javax.swing.border.Border;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.List;

/**
 * <p>
 * 平台应收账款 服务实现类
 * </p>
 *
 * @author yyyyyyyh
 * @since 2023-11-03
 */
@Service
public class SysYszkServiceImpl extends ServiceImpl<SysYszkMapper, SysYszk> implements ISysYszkService {

    @Resource
    private IBuyerOrderService iBuyerOrderService;

    @Override
    public void addYszk(Integer companyId, String trustLimit) {
        // 判断是否已经有记录
        LambdaQueryWrapper<SysYszk> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysYszk::getCompanyId, companyId);
        List<SysYszk> list = this.baseMapper.selectList(wrapper);
        if (list.size() > 0) {
            return;
        }

        // 没有记录，则新增
        SysYszk yszk = new SysYszk();
        yszk.setCompanyId(companyId);
        yszk.setTotalYsAmount(BigDecimal.ZERO);
        yszk.setTotalPayAmount(BigDecimal.ZERO);
        yszk.setTrustLimit(new BigDecimal(trustLimit));
        this.baseMapper.insert(yszk);
    }

    @Override
    public IPage<SysYszkOutVo> getYszkList(SysYszkInVo inVo, Long pageNo, Long pageSize) {
        QueryWrapper<SysYszkOutVo> wrapper = new QueryWrapper<>();
        wrapper.eq((inVo.getCompanyId() != null), "a.company_id", inVo.getCompanyId());
        wrapper.orderByDesc("a.create_time");

        Page<SysYszkOutVo> page = new Page<>(pageNo, pageSize);
        IPage<SysYszkOutVo> iPage = baseMapper.getYszkList(page, wrapper);
        for (SysYszkOutVo e : iPage.getRecords()) {
            // 未结账款 = 应收账款 - 累计充值（为正的时候，为负显示0）
            BigDecimal a = e.getTotalYsAmount().subtract(e.getTotalPayAmount()).compareTo(BigDecimal.ZERO) > 0 ?
                    e.getTotalYsAmount().subtract(e.getTotalPayAmount()) : BigDecimal.ZERO;
            e.setWjzk(a);
            // 充值余额 = 累计充值 - 应收账款（为正的时候，为负显示0）
            BigDecimal b = e.getTotalPayAmount().subtract(e.getTotalYsAmount()).compareTo(BigDecimal.ZERO) > 0 ?
                    e.getTotalPayAmount().subtract(e.getTotalYsAmount()) : BigDecimal.ZERO;
            e.setCzye(b);
        }

        return iPage;
    }

    @Override
    public void sk(SysSkInVo inVo) {
        // 判断是否已经有记录
        LambdaQueryWrapper<SysYszk> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysYszk::getCompanyId, inVo.getCompanyId());
        List<SysYszk> list = this.baseMapper.selectList(wrapper);
        if (list.size() == 0) {
            return;
        }
        SysYszk sysYszk = list.get(0);

        BigDecimal totalPayAmount = sysYszk.getTotalPayAmount();
        BigDecimal trustLimit = sysYszk.getTrustLimit();

        // 判断类型，
        // 累计充值 = 普通充值的和，加上临时授信还款的和
        if (inVo.getType().equals(1)) {
            totalPayAmount = totalPayAmount.add(inVo.getPayAmount());
            sysYszk.setTotalPayAmount(totalPayAmount);
        }

        // 授信额度 = 单位的授信额度 + 临时的授信额度
        if (inVo.getType().equals(2)) {
            trustLimit = trustLimit.add(inVo.getPayAmount());
            sysYszk.setTrustLimit(trustLimit);
        }
        this.baseMapper.updateById(sysYszk);
    }

    @Override
    public void hk(SysHkInVo inVo, BigDecimal payAmount) {
        // 判断是否已经有记录
        LambdaQueryWrapper<SysYszk> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysYszk::getCompanyId, inVo.getCompanyId());
        List<SysYszk> list = this.baseMapper.selectList(wrapper);
        if (list.size() == 0) {
            return;
        }
        SysYszk sysYszk = list.get(0);

        BigDecimal totalPayAmount = sysYszk.getTotalPayAmount();
        BigDecimal trustLimit = sysYszk.getTrustLimit();

        // 判断类型，
        // 累计充值 = 普通充值的和，加上临时授信还款的和
        totalPayAmount = totalPayAmount.add(payAmount);
        sysYszk.setTotalPayAmount(totalPayAmount);

        // 授信额度 = 单位的授信额度 + 临时的授信额度
        // 还款后，取消临时额度
        trustLimit = trustLimit.subtract(payAmount);
        sysYszk.setTrustLimit(trustLimit);

        this.baseMapper.updateById(sysYszk);
    }

    @Override
    public SalerYfzkOutVo getSalerYf() {
        BigDecimal totalOriginalPrice = BigDecimal.ZERO;
        // 判断是否已经有记录
        LambdaQueryWrapper<SysYszk> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysYszk::getCompanyId, TokenService.getUserBytoken().getCompanyId());
        List<SysYszk> list = this.baseMapper.selectList(wrapper);
        if (list.size() == 0) {
            return new SalerYfzkOutVo();
        }
        SalerYfzkOutVo sysYszkOutVo = new SalerYfzkOutVo();
        SysYszk sysYszk = this.baseMapper.selectOne(wrapper.orderByDesc(SysYszk::getCreateTime).last("limit 1"));
        BeanUtils.copyProperties(sysYszk, sysYszkOutVo);
        // 账户累计充值金额
        BigDecimal totalPayAmount = sysYszk.getTotalPayAmount();
        Integer companyId = sysYszk.getCompanyId();
        List<BuyerOrder> buyerOrderList =
                iBuyerOrderService.list(Wrappers.<BuyerOrder>lambdaQuery().eq(BuyerOrder::getDistributorId, companyId));
        for (BuyerOrder buyerOrder : buyerOrderList) {
            totalOriginalPrice = totalOriginalPrice.add(buyerOrder.getTotalOriginalPrice());
        }
        // 账户剩余额度
        BigDecimal balance = totalPayAmount.subtract(totalOriginalPrice);
        sysYszkOutVo.setBalance(balance);
        return sysYszkOutVo;
    }

    @Override
    public IPage<SysYckLogOutVo> getYckLog(SysYckLogInVo inVo, Integer companyId, Long pageNo, Long pageSize) {
        QueryWrapper<SysYckLogOutVo> wrapper = new QueryWrapper<>();
        wrapper.eq("a.distributor_id", companyId);

        // 查询条件
        wrapper.like(StringUtils.hasLength(inVo.getOrderNo()), "a.order_id", inVo.getOrderNo());
        wrapper.like(StringUtils.hasLength(inVo.getVenderOrderNo()), "a.order_id", inVo.getVenderOrderNo());
        wrapper.like(StringUtils.hasLength(inVo.getGoodsName()), "d.goods_name", inVo.getGoodsName());
        wrapper.eq((inVo.getTotlePrice() != null), "CAST((c.sku_quantity * c.sku_price) AS DECIMAL(9, 2))",
                inVo.getTotlePrice());
        wrapper.ge((inVo.getStartTime() != null), "a.pay_time", inVo.getStartTime());
        if (inVo.getEndTime() != null) {
            wrapper.le("a.pay_time", LocalDateTime.of(inVo.getEndTime(), LocalTime.MAX));
        }
        Page<SysYckLogOutVo> page = new Page<>(pageNo, pageSize);
        IPage<SysYckLogOutVo> iPage = this.baseMapper.getListPageByConditions(page, wrapper);

        return iPage;
    }

    @Override
    public void addYszk(BigDecimal totalSalerPrice) {
        LambdaQueryWrapper<SysYszk> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysYszk::getCompanyId, TokenService.getUserBytoken().getCompanyId());
        SysYszk sysYszk = this.getOne(wrapper);
        if (sysYszk != null) {
            sysYszk.setTotalYsAmount(sysYszk.getTotalYsAmount().add(totalSalerPrice));
            this.updateById(sysYszk);
        }
    }
}
